package com.gqz.aircraftwar.mvp.model.bullet

import android.graphics.Canvas
import android.graphics.PointF
import com.gqz.aircraftwar.App
import com.gqz.aircraftwar.mvp.model.aircraft.PlayerAircraft
import com.gqz.aircraftwar.util.MyEnum
import com.gqz.aircraftwar.util.i
import kotlinx.coroutines.*
import java.lang.Exception
import java.util.concurrent.CopyOnWriteArrayList
import kotlin.system.measureTimeMillis

/**
 * 子弹管理器
 *
 * @author gqz
 * @data 2020/3/25
 */

class BulletManager private constructor() {
    val TAG: String = "BulletManager-->"

    private object Holder {
        val instance = BulletManager()
        const val interval = 1000L / 60L
    }

    companion object {
        var instance = Holder.instance
        val ctx = newSingleThreadContext("Bullet")
    }

    var job: Job? = null

    //    var bulletList = mutableListOf<Bullet>()
    var bulletList = CopyOnWriteArrayList<Bullet>()

    fun start() {
        try {
            job = GlobalScope.launch(ctx) {
                i(TAG, "start--> bulletManager worked in ${Thread.currentThread().name}")
                while (App.isRunning) {
//                    d(TAG, "running-->")
                    bulletList.filter { !it.free }.forEach {
                        it.move()
                        //玩家和敌机子弹碰撞
                        bulletList.filter {
                            !it.free && it.dir == MyEnum.Dir.down
                        }.forEach {
                            it.hit(PlayerAircraft.getInstant())
                        }
                    }
                    delay(Holder.interval)
                }
                bulletList.clear()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }
    }

    fun stop() {
        bulletList.clear()
        job?.cancel()
    }

    inline fun generatePlayerBullet(
        pos: PointF,
        speedx: Float = 0f,
        speedy: Float = 10f,
        damage: Float = 1f,
        col: Int = 1
    ) {
        var _col: Int
        if (col < 1) {
            _col = 1
        } else {
            _col = col
        }
        var left = 0f
        var right = 0f
        for (i in 1.._col) {

            var bullet = bulletList.find { it.free && !it.special }
            if (bullet == null) {
                bullet = Bullet(pos.x, pos.y)
                bulletList.add(bullet)
            } else {
                bullet.resetPos(pos)
            }
            bullet.set(speedx, speedy, damage)
            bullet.dir = MyEnum.Dir.up
            bullet.free = false
            bullet.special = false
            bullet.y = pos.y - bullet.bmp.height

            if (_col == 1 || (_col % 2 != 0 && i == 1)) {
                bullet.x = pos.x - bullet.bmp.width / 2

            } else if (_col % 2 == 0) {//列数为偶数
                //TODO: >=4列后，中间保留2列，左右两侧变为斜向发射
                if (i % 2 == 1) {
                    bullet.x = pos.x - bullet.bmp.width + left
                    left -= bullet.bmp.width + 10f
                } else if (i % 2 == 0) {
                    bullet.x = pos.x + right
                    right += bullet.bmp.width + 10f
                }

            } else {//列数为奇数
                //TODO: >=5列后，中间保留3列，左右两侧变为斜向发射
                if (i % 2 == 1) {
                    bullet.x = pos.x - bullet.bmp.width * 1.5f + left
                    left -= bullet.bmp.width + 10f
                } else if (i % 2 == 0) {
                    bullet.x = pos.x + bullet.bmp.width / 2 + right
                    right += bullet.bmp.width + 10f
                }
            }
        }
    }

    inline fun generateEnemyBullet(pos: PointF, speedx: Float) {
        var bullet = bulletList.find { it.free && !it.special }
        if (bullet == null) {
            bullet = Bullet(pos.x, pos.y)
            bulletList.add(bullet)
        } else {
            bullet.resetPos(pos)
        }
        bullet.x = pos.x - bullet.bmp.width / 2
        bullet.dir = MyEnum.Dir.down
        bullet.speedx = speedx
        bullet.free = false
        bullet.special = false
    }

    inline fun generateScatteringBullet(pos: PointF, speedy: Float, damage: Float = 1f) {
        var x = Math.random()
        var plusMinus = (-4..4).random()
        x *= plusMinus * x
        generatePlayerBullet(pos, x.toFloat(), speedy, damage)
    }

    inline fun generateCannonBullet(
        pos: PointF,
        speedy: Float,
        damage: Float = 0.5f
    ) {
        var bullet = bulletList.find { it.free && it is CannonBullet }
        if (bullet == null) {
            bullet = CannonBullet()
            bulletList.add(bullet)
        } else {
            bullet.resetPos(pos)
        }
        bullet.damage = damage
        bullet.x = pos.x - bullet.bmp.width / 2
        bullet.dir = MyEnum.Dir.up
        bullet.speedy = speedy
        bullet.free = false
        bullet.special = true
    }

    inline fun drawAll(canvas: Canvas) {
        bulletList.filter { !it.free }.forEach { it.draw(canvas) }
    }

}
